package com.example.demo.core.security;

import com.example.demo.model.Admin;
import com.example.demo.model.RolePermission;
import com.example.demo.model.User;
import com.example.demo.service.AdminService;
import com.example.demo.service.RolePermissionService;
import com.example.demo.service.UserService;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class MyAuthorizingRealm extends AuthorizingRealm {

    @Autowired
    private UserService userServiceImp;

    @Autowired
    private AdminService adminServiceImp;

    @Autowired
    private RolePermissionService rolePermissionService;

    @Override
    public boolean supports(AuthenticationToken token) {
        return token instanceof JWTToken;
    }



    //在添加注解如 @RequiresPermissions(logical = Logical.AND, value = {"view", "edit"}) 时调用此函数
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String role=JWTUtil.getRole(principalCollection.toString());
        /**
         * 查询角色拥有的权限
         */
        List<String> permissionList= rolePermissionService
                .selectByCondition(role,null)
                .stream()
                .map(RolePermission::getThePermission)
                .collect(Collectors.toList());//通过数据库查询permission,再放到list里面


        SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.addStringPermissions(permissionList);
        simpleAuthorizationInfo.addRole(role);
        return simpleAuthorizationInfo;
    }

    //认证时调用
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        //获得token的用户名
        String token= (String) authenticationToken.getCredentials();
        String name=JWTUtil.getName(token);
        String table=JWTUtil.getTable(token);

        if (name==null||table==null)
        {
            throw new AuthenticationException("token invalid");
        }

        /**
         * 从数据库里面查出密码匹配
         */
        String realPassword;
        if (table.equals("user"))
        {
            List<User> result=userServiceImp.selectByCondition(null,name,null,null);
            if (result.size()==0)
            {
                throw new AuthenticationException("User didn't existed!");
            }
            realPassword=result.get(0).getUserPwd();
        }
        else
        {
            List<Admin> result= adminServiceImp.selectByCondition(null, name, null, null);
            if (result.size()==0)
            {
                throw new AuthenticationException("Admin didn't existed!");
            }
            realPassword=result.get(0).getAdminPwd();
        }


        /**
         * 主要是反解析出所带的token里面的密码是不是正确的
         */
        if (! JWTUtil.verify(name,token,realPassword))
        {
            throw new AuthenticationException("Username or password error");
        }

        return new  SimpleAuthenticationInfo(token,token,getName());
    }
}
